﻿//Copyright © 2012 by Geodata Danmark. All Rights Reserved
//Author: Carsten Helsted

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.Win32;
using System.Runtime.InteropServices;

namespace BrowseByURL
{
    public partial class frmMain : Form
    {


        [DllImport("Shell32", CharSet = CharSet.Auto)]
        private static unsafe extern int ExtractIconEx(
            string lpszFile,
            int nIconIndex,
            IntPtr[] phIconLarge,
            IntPtr[] phIconSmall,
            int nIcons);

        [DllImport("user32.dll", EntryPoint = "DestroyIcon", SetLastError = true)]
        private static unsafe extern int DestroyIcon(IntPtr hIcon);


        public frmMain()
        {
            InitializeComponent();

            //Force this as Default browser
            RegistryKey key = Registry.CurrentUser.OpenSubKey(Program.UserChoiceHTTP, true);
            if (key != null)
                key.SetValue("Progid", "BrowseByURL");

            key = Registry.CurrentUser.OpenSubKey(Program.UserChoiceHTTPS, true);
            if (key != null)
                key.SetValue("Progid", "BrowseByURL");

            string assemblyFile = System.Reflection.Assembly.GetEntryAssembly().Location;

            key = Registry.ClassesRoot.OpenSubKey(Program.ProtocolHTTP, true);
            if (key != null)
                key.SetValue(null, String.Format(@"""{0}"" ""{1}""", assemblyFile, "%1"));

            key = Registry.ClassesRoot.OpenSubKey(Program.ProtocolHTTPS, true);
            if (key != null)
                key.SetValue(null, String.Format(@"""{0}"" ""{1}""", assemblyFile, "%1"));


            //Setup listview handler
            this.lvwURLS.MouseDoubleClick += new MouseEventHandler(lvwURLS_MouseDoubleClick);

            //Prepare dropdownlist 
            cbDefaultBrowser.Items.Clear();
            cbDefaultBrowser.DataSource = Program.InstalledBrowsers;
            cbDefaultBrowser.DisplayMember = "DisplayName";
            cbDefaultBrowser.ValueMember = "Name";

            //Prepare imagelists
            lvwURLS.SmallImageList = new ImageList();
            lvwURLS.LargeImageList = new ImageList();
            foreach(Browser b in Program.InstalledBrowsers)
            {
                System.Drawing.Icon icon = ExtractIconFromExe(b.DefaultIcon,false);
                lvwURLS.SmallImageList.Images.Add(b.Name, icon);

                System.Drawing.Icon icon2 = ExtractIconFromExe(b.DefaultIcon, true);
                lvwURLS.LargeImageList.Images.Add(b.Name, icon2);

                if (b.IsDefaultBrowser)
                    cbDefaultBrowser.SelectedItem = b;
            }

            fillLvwURLS();

        }

        void lvwURLS_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            //Edit URLDef
            if (lvwURLS.SelectedItems.Count > 0)
            {
                ListViewItem li = lvwURLS.SelectedItems[0];
                URLDef u = Program.UrlDefinitions[li.Index];

                if (u != null)
                {
                    frmEditUrlExp f = new frmEditUrlExp(u);
                    f.ShowDialog(this);

                    fillLvwURLS();
                }            
            }
        }

        private void cmdCancel_Click(object sender, EventArgs e)
        {
            //Do not save changes
            this.Close();

        }

        private void fillLvwURLS()
        {
            //Reload listview with urldefs
            lvwURLS.Items.Clear();
            foreach (URLDef u in Program.UrlDefinitions)
            {
                ListViewItem li = new ListViewItem(u.URLExp, u.UseBrowser.Name);
                lvwURLS.Items.Add(li);
            }
        }

        public static Icon ExtractIconFromExe(string file, bool large)
        {
            unsafe
            {
                int readIconCount = 0;
                IntPtr[] hDummy  = new IntPtr[1] {IntPtr.Zero};
                IntPtr[] hIconEx = new IntPtr[1] {IntPtr.Zero};

                try
                {
                    if(large)
                        readIconCount = ExtractIconEx(file,0, hIconEx, hDummy, 1);
                    else
                        readIconCount = ExtractIconEx(file,0, hDummy, hIconEx, 1);

                    if(readIconCount > 0 && hIconEx[0] != IntPtr.Zero)
                    {
                        // GET FIRST EXTRACTED ICON
                        Icon extractedIcon = (Icon)Icon.FromHandle(hIconEx[0]).Clone();

                        return extractedIcon;
                    }
                    else // NO ICONS READ
                    return null;
                }
                catch(Exception ex)
                {
                    /* EXTRACT ICON ERROR */

                    // BUBBLE UP
                    throw new ApplicationException("Could not extract icon", ex);
                }
                finally
                {
                    // RELEASE RESOURCES
                    foreach(IntPtr ptr in hIconEx)
                    if(ptr != IntPtr.Zero)
                        DestroyIcon(ptr);

                    foreach(IntPtr ptr in hDummy)
                    if(ptr != IntPtr.Zero)
                        DestroyIcon(ptr);
                }
            }
        }

        private void cmdOK_Click(object sender, EventArgs e)
        {
            //Save changes

            RegistryKey key = Registry.CurrentUser.OpenSubKey(Program.BrowseByUrlKey, true);
            if (key == null)
            {
                key = Registry.CurrentUser.CreateSubKey(Program.BrowseByUrlKey);
            }

            if (key != null)
            {
                //Start by clearing previouse setup
                foreach (var v in key.GetSubKeyNames())
                {
                    key.DeleteSubKeyTree(v, false);
                }

                //create key stubs
                foreach (Browser b in Program.InstalledBrowsers)
                {
                    key.CreateSubKey(b.Name);
                    b.IsDefaultBrowser = false;
                }

                //Save URLDefs
                int count = 1;
                foreach (URLDef u in Program.UrlDefinitions)
                {
                    RegistryKey browserKey = key.OpenSubKey(u.UseBrowser.Name, true);
                    if (browserKey != null)
                    {
                        browserKey.SetValue(String.Format(@"URL_{0}", count), u.URLExp.ToString());
                        count++;
                    }
                }
            }

           
            //Save default browser
            Browser defBrowser = (Browser)cbDefaultBrowser.SelectedItem;
            defBrowser.IsDefaultBrowser = true;
            if(defBrowser != null)
            {
                key.SetValue("DEFAULT_BROWSER", defBrowser.Name);
                this.Close();
            }
        }


        private void lvwURLS_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void cmdAdd_Click(object sender, EventArgs e)
        {
            //Add new URLDef
            frmEditUrlExp f = new frmEditUrlExp(null);
            f.ShowDialog(this);

            fillLvwURLS();

        }

        private void cmdRemove_Click(object sender, EventArgs e)
        {
            //Remove URLDef
            if (lvwURLS.SelectedItems.Count > 0)
            {
                ListViewItem li = lvwURLS.SelectedItems[0];
                URLDef u = Program.UrlDefinitions[li.Index];

                if (u != null)
                {
                    li.Remove();
                    Program.UrlDefinitions.Remove(u);
                }
            }
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            frmAbout f = new frmAbout();
            f.ShowDialog(this);
        }
    }
}
